#ifndef _CRT_QUEUE_H_
#define _CRT_QUEUE_H_

#include <crt_define.h>

#ifdef	__cplusplus
extern "C" 
{
#endif


typedef struct _queue_s  _queue_t;

struct _queue_s {
	_queue_t  *prev;
	_queue_t  *next;
};


#define _queue_init(q)															\
    (q)->prev = q;																\
    (q)->next = q

#define _queue_empty(h)															\
    (h == (h)->next)


#define _queue_insert_head(h, x)												\
    (x)->next = (h)->next;														\
    (x)->next->prev = x;														\
    (x)->prev = h;																\
    (h)->next = x


#define _queue_insert_after   _queue_insert_head


#define _queue_insert_tail(h, x)												\
    (x)->prev = (h)->prev;														\
    (x)->prev->next = x;														\
    (x)->next = h;																\
    (h)->prev = x


#define _queue_head(h)															\
    (h)->next


#define _queue_last(h)															\
    (h)->prev


#define _queue_sentinel(h)														\
    (h)


#define _queue_next(q)															\
    (q)->next


#define _queue_prev(q)															\
    (q)->prev


#define _queue_remove(x)														\
    (x)->next->prev = (x)->prev;												\
    (x)->prev->next = (x)->next


#define _queue_split(h, q, n)													\
    (n)->prev = (h)->prev;														\
    (n)->prev->next = n;														\
    (n)->next = q;																\
    (h)->prev = (q)->prev;														\
    (h)->prev->next = h;														\
    (q)->prev = n;


#define _queue_add(h, n)														\
    (h)->prev->next = (n)->next;												\
    (n)->next->prev = (h)->prev;												\
    (h)->prev = (n)->prev;														\
    (h)->prev->next = h;


#define _queue_data(q, type, link)                                         \
    (type *) ((u_char *) q - offsetof(type, link))


/*

typedef struct
{
int x;
} my_point_t;


typedef struct
{
my_point_t point;
_queue_t queue;

} my_point_queue_t;

void dump_queue_from_tail(_queue_t *que)
{

_queue_t *q = _queue_last(que);

printf("(0x%x: (0x%x, 0x%x)) <==> \n", que, que->prev, que->next);

for (; q != _queue_sentinel(que); q = _queue_prev(q))
{
my_point_queue_t *point = _queue_data(q, my_point_queue_t, queue);
}

}

int my_point_cmp(const _queue_t* lhs, const _queue_t* rhs)

{

my_point_queue_t *pt1 = _queue_data(lhs, my_point_queue_t, queue);
my_point_queue_t *pt2 = _queue_data(rhs, my_point_queue_t, queue);
if (pt1->point.x % 2 == 0)
return 1;
return 0;
}


void dump_queue_from_head(_queue_t *que)
{

_queue_t *q = _queue_head(que);
printf("(0x%x: (0x%x, 0x%x)) <==> \n", que, que->prev, que->next);
for (; q != _queue_sentinel(que); q = _queue_next(q))
{

my_point_queue_t *point = _queue_data(q, my_point_queue_t, queue);

}

}



my_point_queue_t *point;
_queue_t* myque = malloc(sizeof(_queue_t));  //alloc a queue head
_queue_init(myque);

for (int i = 0; i < 100; i++) {

	point = malloc(sizeof(my_point_queue_t));
	point->point.x = i;
	_queue_init(&point->queue);
	_queue_insert_head(myque, &point->queue);
}



dump_queue_from_tail(myque);
_queue_sort(myque, my_point_cmp);
dump_queue_from_tail(myque);
*/


_queue_t* queue_middle(_queue_t *queue);
void queue_sort(_queue_t *queue, int(*cmp)(const _queue_t *, const _queue_t *));


#ifdef	__cplusplus
}
#endif

#endif

